If you have been reading anything about software development in the past few years, you have been somewhat bombarded by OLE discussions. These next two chapters are intended to be a first start. While the space we have here does not allow an in-depth
definitive work, these chapters will explain what OLE is, what it isn't, and will show you how to apply this exciting new technology. This chapter will provide an overview of OLE and will illustrate how to add OLE to your projects.
If you are new to Visual Basic and have not spent much time with the system, the concepts in this chapter may appear obscure at first. If you stick with it, however, you'll find that the results are worth the struggle.
Almost everything written about Windows development discusses objects or OLE (Object Linking and Embedding). Objects are a method to help you raise the functionality and reliability of your development efforts.
Visual Basic 4.0 is an object-oriented language, which means you manipulate objects to develop programs instead of typing in a lot of code. For example, you take an existing control like the text box and place it onto a form. This text box control
contains events, methods, and properties. That is, it contains data (such as the properties that you set to your needs) and code (such as the code to control the object).
These three classes of features (events, methods, and properties) to this control are pre-programmed for you. You can use these features without additional programming by following the rules laid out by the original developer (Microsoft, in this case)
of this control.
In the past, programs were monolithic. You had to include all of the features you wanted as code. As the computer industry evolved, operating systems began to increase in functionality and to provide additional features that application programs could
call. For example, instead of writing the code to put the data on the screen, developers could now call a built-in function of the operating system to perform this action for them. The operating system's built-in functions were called the API (Application
Programming Interface).
One problem that developers encountered was inconsistency between applications on the same platform (DOS, for example). The keystrokes they used for a particular spreadsheet most likely were not the same as the keystrokes of their word processor. The
emergence of Windows 3.0 solved this problem by enforcing consistency across all application interfaces.
Now that the applications looked similar, the issue was how to get them to work together. One solution was DDE (Dynamic Data Exchange), which is a widespread implementation that used different applications to perform different functions. Developers
could now use a spreadsheet to perform calculations and a database program to store the results. They could put these multiple interfaces and applications together into one application solution.
DDE, for all of its power, was limited. It was based upon the client/server model and was message based. As a result, getting two applications to work together involved a lot of programming. To address this issue and other issues, Microsoft released OLE
1.0.
OLE 1.0 was the first major effort that was available in a widespread fashion that attempted to increase the ability of applications to work together.
OLE 1.0 was really intended to expose developers to the concepts of objects. The operating system platform at the time of OLE 1.0 shipment (such as Windows 3.0 and Windows 3.1 ) was not sufficient to exploit this technology but was adequate to get
developers started with using it. Even Microsoft OLE between Excel and Word, for example, was not reliable in its first release. Also, OLE 1.0 did not provide a full set of APIs that allowed full implementation of the technology from a programming point of
view.
OLE 2.0 is focused upon the Windows 95 and Windows NT platforms. Windows NT (in my view) is by far the more stable platform for serious OLE development. OLE 2.0 includes several enhancements that are significant. Perhaps the most significant is REMOTE
OLE capability. This requires Windows 95 or Windows NT 3.51 or greater.
These two operating systems make it easier for objects to be called and used because they provide a new kind of interface at the programming level called the REGISTRY. This means that the applications that we develop can install themselves into the
REGISTRY of either Windows 95 or Windows NT 3.51. Thus, these applications become part of these operating systems.
OLE 2.0 also supports components, another significant enhancement. For example, Excel 5.0 contains many objects. Older implementations of OLE would allow one call or one interface to Excel as an object. That is, Excel (the entire application) was one
object. OLE 2.0 allows applications to define complex hierarchical interfaces (called "Collections" in Visual Basic 4.0 speak). This enables Excel to expose over 100 components that another application can use. For example, we could theoretically
call the Excel grid control and completely control it from a Visual Basic program.
OLE enables you to paste data and a controlling piece of software into another application. The recipient application has containers that enable it to accept this new kind of interface. Now, for example, you can take the functionality of AutoCAD and
paste it inside of a Visual Basic application.
How can this capability help you and your users? Consider the following example. AutoCAD is an excellent CAD (Computer-Aided Drawing) system, but it stores its data (drawing files) in a highly compressed numerical database that is proprietary. Although
AutoCAD has facilities for keeping information about the drawings, it is not very good at performing traditional database functions. This is the kind of situation in which OLE can really help you and, more importantly, your end users.
You can take a simple application in Visual Basic that uses an Access database (or XBase) to store things like project name, author, description, date of last revision, and so on. On this same screen, you can place an OLE container that allows you to
put the AutoCAD and the Access data together at the same time. To perform this function without OLE would take a tremendous programming effort. An example follows this section that illustrates this concept.
OLE enables you to create an application that merges data and applications from multiple sources. The authors of the different applications you use do not have to program their applications to know about each other in advance. The programmers at
Autodesk (authors of AutoCAD) wrote their application to support OLE functionality as Microsoft did with Visual Basic. After both of these applications were shrink-wrapped and shipped, you could merge them into a custom solution that provides more power to
the user.
The other major benefit to OLE is time savings. Not only can you accomplish the things mentioned in the previous paragraphs, but learning how to do it is not that difficult once you master some new skills.
Note that OLE requires a more powerful computer to run successfully than a normal Windows environment. The best thing you can do for your end users is to get them to a computer that is Windows NT capable (486/66 or higher with 16 M of RAM). This level
of system will provide you with the speed and memory needed to effectively run OLE applications.
When you implement OLE, you can choose to embed or link an object. Linking is intended for applications where the changes in data are important. A monthly sales analysis is a good example of this type of application. You can create the charts and
numbers in Excel and paste the spreadsheet object into a Word document. Each time a user loads the Word document, a current copy of the Excel data is also loaded without any additional interaction from the end user.
When you create a link, the OLE interface and Windows create a hexadecimal named file that contains the data necessary to maintain the source and destination objects together. This file also contains the data necessary for the graphic to display your
image (kind of like a large thumbnail icon). The location of this file will vary based on your system setup. In Windows 3.x, if you defined a TEMP directory setting in your AUTOEXEC.BAT file, it would be located in this directory. If you do not make this
setting, it will be in another link location. That is, if you have a spreadsheet in Excel that includes a WORD document, the link (absent the setting above) would be in the Excel directory where the spreadsheet was started.
Since most applications in Windows will have a graphical image of some sort, the OLE function can use this image to place into the OLE container that you place upon a form.
In the AutoCAD/Access example, you can take a small image that AutoCAD created and store it in the container in the Visual Basic application. The end user can then see a thumbnail of the drawing along with the data from the Access database about the
drawing name, project, and so on. When you link the object, you can now double-click on the image in the OLE container and launch AutoCAD with that image open.
Each application that supports OLE must install the features of the OLE API it supports into the Windows registry. Then any application that is OLE-compliant can use this functionality. The registry is a global database that enables object-oriented
features of a given application to be exposed by the definitions found here. Another way of saying this is that you can extend the operating system with applications you develop by adding them to the registry! If you have not played around with the
registry, select Windows' Run command and enter Regedit in the dialog box that appears to see what this does for you.
Embedding is similar to linking except that the data from the source application is cloned and placed in its entirety into the destination object. Embedding is intended for documents in which the data is either static or is not going to be on the
machine where the data was authored. For example, you may embed an object in a compound document that you are going to give to another user of another computer.
When you embed one object into another object, the destination object can become quite large.
Embedding is also the way to go if you're working on a network. Sometimes you can get links to work on a network, but linking is not recommended. OLE is not network tested. Microsoft is working on distributed OLE as you read this chapter; expect it soon
from a dealer near you.
In traditional object-oriented definitions, a class is a general group of objects that share common attributes. For example, you might have a class of transportation vehicles called Vehicles. This class would share common properties, such as engine,
capacity, and so on. You could then extend these properties to subclasses. This process is called inheritance in OOP (object-oriented programming). If you had Truck as a subclass of the Vehicle class, the Truck subclass would have the same properties
(engine, capacity, and so on) as the Vehicle class because it is a subclass of the Vehicle class. The Truck subclass is said to be dependent upon the Vehicle class because it inherits some of its properties from that class.
In Visual Basic 4.0, classes are somewhat different. You define the classes you are going to use in a class module. A class module is like the code module in Visual Basic 3.0 except that the class module pertains expressly to classes. When your code
calls one of the class modules, that module creates a class or an object.
Suppose that you want to create a class of object that you can use to turn on and off a light switch. You might take the following steps:
This previous example is not complex, but it does illustrate several new features of Visual Basic 4.0. The class module you created and named SwitchPlate is a new class of object for this application. By declaring SwitchStatus in this module, you made
SwitchStatus a property of SwitchPlate. You can access this property the same way you access the properties for the standard Visual Basic controls.
The LightStatus code in Form1 (both set and get procedures) creates an object at run time that has the properties of the SwitchPlate class. Each time you execute this code, you activate an instance of the SwitchPlate class. The last code segment creates
a method for this class (TurnLightsOn).
You have created a new class with properties, multiple instances, and its own method. The capability to create objects with full object-oriented capability is new to Visual Basic 4.0. The ease of Visual Basic and the power of OOP is a tough combination
to beat!
Imagine what you can do with this technology. You could write a standard printer header routine for reports that cannot be written with the report writer and then call the routine in other code forever. Now if you could just persuade Microsoft to allow
developers to create DLLs with Visual Basic _
This chapter previously used an AutoCAD example to demonstrate how you could use OLE to combine multiple data types. In the following procedure, you create the drawing management system for AutoCAD that allows end users to select the drawing they want
by looking at it from inside of AutoCAD. By following this example step by step, you can get a feel for how you can combine multiple data types and multiple application types. If you don't have AutoCAD, keep in mind that this code will also work with other
OLE-compliant applications.
Start a new project and name it DrawMgt1. On Form1 (see figure 18.1), you need to place several controls. (Note that the example project in the figures is using Windows 95 as a testing platform.)
Figure 18.1. The form you need to create for the drawing management program.
Starting from the upper left corner of the form and moving downward, the following steps describe each control you need to add:
After you set up all the controls on the form, start up Access and create a new database named WINSEM1. When Access displays your new database, create a new table named DRAWINGS with the following fields and properties:
PRIMARY KEY FIELD FDRAWNUM TEXT 8 FDRAWNUM TEXT 30 FDRAWDATE DATE/TIME FPROJECT TEXT 30 FPROJMGT TEXT 30 FDESIGNED TEXT 30 FDRAWN TEXT 30 FCHECKED TEXT 30 FCOST OLE/Object FDRAWPATH TEXT 30
In the Visual Basic form, insert a data control named Data1. Set the Database property to WINSEM1, which you just created. Then set the Data1.Recordsource property to the Drawings table.
Next, bind each field in the text boxes to the appropriate field in the table as follows:
TextBox: FDRAWNUM Bound To Data1.FDRAWNUM
TextBox: FDRAWNAME Bound To Data1.FDRAWNAME
TextBox: FDRAWDATE Bound To Data1.FDRAWDATE
TextBox: FPROJECT Bound To Data1.FPROJECT
TextBox: FPROJMGT Bound To Data1.FPROJMGT
TextBox: FDESIGNED Bound To Data1.FDESIGNED
TextBox: FDRAWN Bound To Data1.FDRAWN
TextBox: FCHECKED Bound To Data1.FCHECKED
TextBox: FCOST Bound To Data1.FCOST
You may notice that you do not have an OLE field for the AutoCAD drawing. This omission is related to an incompatibility between Access 2.0 and Visual Basic 3.0. Each OLE object contains a wrapper that the destination object uses to store and retrieve
the sending object. Access 2.0 and Visual Basic 3.0 did not use the same wrapper, so if you are using these products, you cannot stuff an OLE object directly into an Access OLE field. This example shows a workaround for this problem that may be useful to
you when you create other applications.
You now need to create six command buttons below the Data Access Object (or DAO). Create the first button using this code:
NAME = cmdnewdraw; CAPTION = NE&W
Attach the following code to the preceding button's Click event:
Private Sub cmdNewDraw_Click() AddedNew = "T" Data1.Recordset.AddNew cmdSaveNew.Visible = True Dir1.Visible = True Drive1.Visible = True File1.Visible = True FDRAWNUM.MaxLength = 8 FDRAWNAME.MaxLength = 30 FDRAWDATE.MaxLength = 8 FPROJECT.MaxLength = 30 FPROJMGT.MaxLength = 30 FDESIGNED.MaxLength = 30 FDRAWN.MaxLength = 30 FCHECKED.MaxLength = 30 FDRAWNUM.SetFocus End Sub
Create the next button:
NAME = cmdexit; CAPTION = E&XIT
Then attach the following code to the preceding button's Click event:
Private Sub cmdExit_Click() End End Sub
Create the next button:
NAME = cmdsavenew; CAPTION = &SAVE
Then attach the following code to the preceding button's Click event:
Private Sub cmdSaveNew_Click() Dir1.Visible = False Drive1.Visible = False File1.Visible = False cmdSaveNew.Visible = False Dim FileNum ' Declare variable. FileNum = FreeFile ' Get a valid file number. YFilePath = Dir1.Path FileName = FDRAWNUM.Text sFileName = YFilePath & "\" & FileName & ".OLE" Open sFileName For Binary As FileNum ' Open file to save FDRAWOBJ.FileNumber = FileNum ' Set the filenumber. FDRAWOBJ.Action = OLE_SAVE_TO_FILE Data1.Recordset.Update Close #FileNum ' Close the file. AddedNew = "F" Data1.Recordset.MoveLast End Sub
This example doesn't implement the following three buttons, but they demonstrate how you could easily add features that would make life simpler for the end user:
NAME = cmdbydrawnum; CAPTION = N&UMBER NAME = cmdbydrawname; CAPTION = &NAME NAME = cmdbydrawdate; CAPTION = &DATE
On Form1, add the following code to the Form Load event:
Private Sub Form_Load() AddedNew = "F" End Sub
At the top center of Form1, add a label named LABEL10 and set its caption to DRAWING PATH. Just below this label, insert a text box and set its name to FDRAWPATH. Below this text box insert a DriveListBox and set its name to Drive1. Just below the
Drive1 control insert a DirListBox and set its name to Dir1. Double-click on the DirListBox control and attach the following code to its Change event:
Private Sub Dir1_Change() File1.Path = Dir1.Path ' Set File path. End Sub
Below the DirListBox control, insert a FileListBox control and set its name to FILE1. Then attach the following code to its DoubleClick event:
Private Sub File1_DblClick() Dim xFilename As String FDRAWOBJ.Class = "AutocadDrawing" If Right(File1.Path, 1) <> "\" Then xFilename = File1.Path & "\" & File1.FileName Else xFilename = File1.Path & File1.FileName End If FDRAWPATH = File1.Path FDRAWOBJ.SourceDoc = xFilename FDRAWOBJ.Action = OLE_CREATE_FROM_FILE FDRAWOBJ.Action = OLE_ACTIVATE Data1.Recordset("FDrawPath").Value = xFilename AddedNew = "T" End Sub
Create a module file (code file) and insert the following code into it:
Global Const OLE_CREATE_NEW = 0 Global Const OLE_CREATE_FROM_FILE = 1 Global Const OLE_COPY = 4 Global Const OLE_PASTE = 5 Global Const OLE_UPDATE = 6 Global Const OLE_ACTIVATE = 7 Global Const OLE_EXECUTE = 8 Global Const OLE_CLOSE = 9 Global Const OLE_DELETE = 10 Global Const OLE_SAVE_TO_FILE = 11 Global Const OLE_READ_FROM_FILE = 12 Global Const OLE_CONVERT_TO_TYPE = 13 Global AddedNew Global xFilename
Lastly, insert a large OLE container control to the right of your drive controls and set its Name property to FDRAWOBJ. Now you're ready to run the application. Start the application, and then click on the New command button. Your screen should display
something similar to Figure 18.2.
Figure 18.2. The drawing management program's execution screen.
Notice that the directory box becomes illuminated, which prompts the user to find the correct directory. Watch the text box at the top of the screen and notice that the path is built as the user clicks on the directory he wants to be in. When the user
double-clicks on a drawing file, AutoCAD launches, as shown in Figure 18.3.
Figure 18.3. The AutoCAD drawing screen.
Notice that AutoCAD was invoked with the drawing that you selected. To get back to the Visual Basic application, all you need do is type END at the AutoCAD prompt. Now you can enter the data you want to attach to this drawing and click on Save.
The Visual Basic screen now looks like Figure 18.4.
Figure 18.4. The finished screen of the drawing management program.
You can use the arrows on the data control to move to the drawing you want. When you find it, double-click in the OLE container and AutoCAD starts up with the drawing that you selected. When you exit AutoCAD, control returns to the Visual Basic
application at the spot you left it.
Another application of OLE is OLE Automation. OLE Automation is the capability of using features of another OLE-compliant program remotely from your Visual Basic application. For example, Microsoft Excel contains many programmable objects. You can
selectively use these objects through your Visual Basic interface.
Microsoft has been embedding a script form of Visual Basic into many of their products called Visual Basic for Applications or VBA. Not all Microsoft applications are fully implemented with VBA. In the following procedure, you are going to provide an
example of OLE Automation using Word Basic in Microsoft Word.
I recently worked on a system for a client (I develop custom software for corporate clients) in Visual Basic. This client manufactures large industrial equipment that it in turn sells throughout the world. This equipment is very large and complex. The
quoting process is also very complex. Frequently this client must respond to formal requests for proposals with the pricing data as well as engineering and other data that is requested by the potential customer.
I developed a system to create the quote, but a simple printout was not enough of a solution for the proposal problem. Enter OLE Automation. Now the user can drag the quote they want and drop it on a Microsoft Word icon. This icon executes code that
invokes Word as an object that is managed by Visual Basic. The quoting data is then sent to Word through this object management. The result is the quote data formatted in a Word document that the user can then modify as she wishes.
The following steps outline this type of program:
Figure 18.5. Visual Basic OLE Automation development screen.
Figure 18.6. Word showing results from Visual Basic.
Although this example is fairly simple, you can extend its basic concepts dramatically to solve real-world problems like the one mentioned at the beginning of this section. By using other applications to solve end user problems, you can implement more
sophisticated (and more reliable) systems in less time.
OLE can involve multiple sources of data and the objects that control them. Your system must have a host or destination object where the control of the application resides. So far, all of the examples in this chapter use Visual Basic as the front end
and host or destination application, and the objects that you use are sources or clients. For example, when you use Microsoft Word, your application is binding some of Words objects into your Visual Basic application. The Word executables do not exist in
your Visual Basic application. In that sense, your application is a client of some of the Microsoft Word functionality.
Terminology is confusing now because of the convergence of many concepts and technologies. For example, client/server terms also apply to DDE and SQL data access. However, these terms mean slightly different things in each of these application areas.
Basically, one application must act as a server to another application. The requesting application is the client because it is requesting the other application (the server) to do something. For example, Word has a built-in programming language called
Word Basic. When you declare Word as an object, it first has to install itself as an object when the initial installation is performed. By that I mean any application that is going to provide OLE services must install a section into the system registry to
identify itself as an object and to define what services it is going to provide.
The OLE-compliant application (the one you are creating) calls upon the OLE-supplied services of Word as defined in the Registry. In other words, your code requests Microsoft Word do to something. The OLE definition makes the link between the two
applications, but the actual execution of the code occurs within Word.
Note that when you activate an object, you are running the application in which the object resides. When you click on the image of an AutoCAD drawing, for example, you are executing AutoCAD with the data represented by the image. For this reason, you
need at least a 486/66 with 16 M of RAM to run OLE-enabled applications.
An OLE server is an application that contains objects that have been exposed to the entire system by installing a definition of what functions the application supports and how they are called. In earlier examples, both Microsoft Word and AutoCAD acted
as OLE servers to the Visual Basic application. With Visual Basic 4.0, a Visual Basic application can now register itself as an OLE-compliant application.
Many people made complaints about Visual Basic 3.0's Setup program. As a result, the Setup Wizard has been dramatically improved in version 4.0. All you need to do to get an OLE-compliant object installed into the Registry is to make your class Public
when it is defined at the application level. Then choose the Setup Wizard command from the Visual Basic menu.
Use the CLASSEX example to see how this process works. You should have a folder or directory off Visual Basic named Setupkit. This example uses the kitfl32 for the 32-bit setup program. Your screen should look like Figure 18.7.
Figure 18.7. The Visual Basic Setupkit screen.
Execute the Setup icon and follow the on-screen prompts. When prompted for the DAO object (it should be something like DAO2532.tlb), point to the c:\windows\msapps\DAO directory to locate it. After compression, the system creates a SETUP.EXE file on a
floppy disk (you will need two floppy disks). After the system has finished copying the program to disk, run the Setup program from the floppy disk.
You should now be able to go into the Regedit program by selecting the Run command and entering Regedit in the dialog box that appears. Your initial screen should look like Figure 18.8.
Figure 18.8. The Windows 95 Registry Editor.
Open the Edit menu and select the Find command. When prompted, enter CLASSEX (the name of your executable file). You should now see CLASSES as an object on screen, as shown in Figure 18.9.
Figure 18.9. The installed object in the registry.
CLASSEX.EXE is now a part of the registry on the computer shown in Figure 18.9. What this means is that you can now execute CLASSEX without a path or icon by entering its name in the Run dialog box.
In-place editing is the capability to use an OLE compliant application to create or edit data in a VB OLE container. For example, you can run a copy of Excel inside of a VB container that you have placed on a form.
One of the biggest advantages of OLE is the ease of use it offers to end users. You can combine multiple applications and control them from Visual Basic the entire time. Take a look at Form1 in Figure 18.10.
Figure 18.10. The OLE in-place editing layout screen.
As you can see, this application allows for multiple OLE data types. To create this application, follow these steps:
Now execute the program and click on the AutoCAD button.
As you can see, you now have AutoCAD running in a window of your Visual Basic application, as shown in Figure 18.11.
Figure 18.11. OLE in-place editing of an AutoCAD drawing.
You can use AutoCAD as if you were executing the application from an icon. The difference is that you return to your Visual Basic application when you type end. The screen now looks like Figure 18.12.
Figure 18.13 shows a screen with a Paintbrush image. As you can see, there are some slight differences in how various applications execute underneath OLE.
Figure 18.12. Visual Basic OLE in-place editing showing the OLE container.
Figure 18.13. OLE in-place editing with Paintbrush.
As you have seen in this chapter, OLE is a very versatile programming concept that extends itself to many types of applications and assists with many programming chores. Hopefully, the examples in this chapter have demonstrated just how powerful this
technology has become. Don't be left behind; learn OLE now. The examples in this chapter are simple by design. You should be able to enter and execute them with minimal difficulty. Then you can take these examples and extend them into a real-world
scenario.
Good luck!